#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <sw/redis++/redis++.h> 
#include "util.hpp"

void test1(sw::redis::Redis &redis)
{
    std::cout << "get And set 使用" << std::endl;
    redis.flushall();

    redis.set("key", "value");
    auto value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    }

    redis.set("key", "222");
    value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    }
}

void test2(sw::redis::Redis &redis)
{
    using namespace std::chrono_literals;

    std::cout << "set 带有超时时间" << std::endl;
    redis.flushall();

    redis.set("key", "111", 10s);

    long long time = redis.ttl("key");
    std::cout << "time: " << time << std::endl;
}

void test3(sw::redis::Redis &redis)
{
    std::cout << "set NX 和 XX 使用" << std::endl;
    redis.flushall();

    redis.set("key", "111", std::chrono::seconds(0), sw::redis::UpdateType::NOT_EXIST);

    auto value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    } else {
        std::cout << "value 不存在" << std::endl;
    }
}

void test4(sw::redis::Redis &redis)
{
    std::cout << "mset 使用" << std::endl;
    redis.flushall();

    // 方法一：使用初始化列表
    // redis.mset({std::make_pair("key", "111"), std::make_pair("key2", "222"), {"key3", "333"}});

    // 方法二：迭代器
    std::vector<std::pair<std::string, std::string>> keys = {
        {"key", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };

    redis.mset(keys.begin(), keys.end());

    auto value = redis.get("key");
    if(value) {
        std::cout << "key -> valur: " << value.value() << std::endl;
    }

    value = redis.get("key2");
    if(value) {
        std::cout << "key2 -> valur: " << value.value() << std::endl;
    }

    value = redis.get("key3");
    if(value) {
        std::cout << "key3 -> valur: " << value.value() << std::endl;
    }
}

void test5(sw::redis::Redis &redis)
{
    std::cout << "mget 使用" << std::endl;
    redis.flushall();

    std::vector<std::pair<std::string, std::string>> keys = {
        {"key", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };

    redis.mset(keys.begin(), keys.end());

    std::vector<sw::redis::OptionalString> result;
    auto it = std::back_insert_iterator(result);
    redis.mget({"key", "key2", "key3", "key4"}, it);

    printContainerOptional(result);
}

void test6(sw::redis::Redis &redis)
{
    std::cout << "getrange 和 setrange 使用" << std::endl;
    redis.flushall();

    redis.set("key", "abcdefghijklmn");

    std::string result = redis.getrange("key", 2, 5);
    std::cout << "result: " << result << std::endl;

    redis.setrange("key", 2, "xyz");
    auto value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    }
}

void test7(sw::redis::Redis &redis)
{
    std::cout << "incr 和 decr 使用" << std::endl;
    redis.flushall();

    redis.set("key", "100");

    long long result = redis.incr("key");
    std::cout << "result: " << result << std::endl;

    auto value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    }

    result = redis.decr("key");
    std::cout << "result: " << result << std::endl;

    value = redis.get("key");
    if(value) {
        std::cout << "value: " << value.value() << std::endl;
    }
}

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");

    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    // test6(redis);
    test7(redis);
    
    return 0;
}